; 代码清单8-2
; 文件说明: 用户程序
; 创建时间: 2024-09-23 21:58

; =======================================================
SECTION header vstart=0     ; 定义用户程序头部
    program_length     dd program_end              ; 程序长度[0x00]

    ; 程序入口
    code_entry         dw start                    ; 偏移地址[0x04]
                        dd section.code_1.start     ; 段地址[0x06]

    realloc_tbl_len    dw (head_end-code_1_segment)/4  ; 重定位表项数[0x0a]

    code_1_segment     dd section.code_1.start     ;[0x0c]
    code_2_segment     dd section.code_1.start     ;[0x10]
    data_1_segment     dd section.code_1.start     ;[0x14]
    data_2_segment     dd section.code_1.start     ;[0x18]
    stack_segment      dd section.code_1.start     ;[0x1c]

    head_end:

; =======================================================
SECTION code_1 align=16 vstart=0    ; 定义代码段1
; --------------------打印字符串--------------------------
; 输入 DS:BX地址开始,0值结束
; 输出: 显示
put_string:

        mov cl, [bx]
        or cl, cl
        jz .exit        ; 字符值=0
        call put_char
        inc bx          ; 下一个字符
        jmp put_string

    .exit:
        ret
; -------------------打印单个字符--------------------------
; 输入: cl
; 输出: 显示
put_char:

        push ax
        push bx
        push cx
        push dx         ; 保存环境
        push ds
        push ss




        pop ss
        pop ds
        pop dx
        pop cx          ; 恢复环境
        pop bx
        pop ax

        ret

    start:
        ; 初始化栈地址
        mov ax, [stack_segment]     ; 栈段地址
        mov ss, ax
        mov sp, stack_end           ; 栈指针

        mov ax, [data_1_segment]    ; 数据段地址指向数据段1
        mov ds, ax

        mov bx, msg0                ; 字符串起始地址 DS:BX
        call put_string

        mov ax, [es:code_2_segment]
        push ax
        mov ax, begin
        push ax

        retf

    continue:
        mov ax, [es:data_2_segment]     ; 数据段指向数据段2
        mov ds, ax

        mov bx, msg1
        call put_string

        jmp $
; =======================================================
SECTION code_2 align=16 vstart=0    ; 定义代码段2

    begin:
        push word [es:code_1_segment]   ; 代码段1段地址
        mov ax, continue
        push ax                         ; 偏移地址

        retf                        ; 转移到代码段1

; =======================================================
SECTION data_1 align=16 vstart=0    ; 定义数据段1

    msg0 db '  This is NASM - the famous Netwide Assembler. '
         db 'Back at SourceForge and in intensive development! '
         db 'Get the current versions from http://www.nasm.us/.'
         db 0x0d,0x0a,0x0d,0x0a
         db '  Example code for calculate 1+2+...+1000:',0x0d,0x0a,0x0d,0x0a
         db '     xor dx,dx',0x0d,0x0a
         db '     xor ax,ax',0x0d,0x0a
         db '     xor cx,cx',0x0d,0x0a
         db '  @@:',0x0d,0x0a
         db '     inc cx',0x0d,0x0a
         db '     add ax,cx',0x0d,0x0a
         db '     adc dx,0',0x0d,0x0a
         db '     inc cx',0x0d,0x0a
         db '     cmp cx,1000',0x0d,0x0a
         db '     jle @@',0x0d,0x0a
         db '     ... ...(Some other codes)',0x0d,0x0a,0x0d,0x0a
         db 0

; =======================================================
SECTION data_2 align=16 vstart=0    ; 定义数据段2

    msg1 db '  The above contents is written by LeeChung. '
         db '2011-05-06'
         db 0

; =======================================================
SECTION stack align=16 vstart=0     ; 定义堆栈段

        resb 256

stack_end:

; =======================================================
SECTION trail align=16              ; 定义程序尾部
program_end: